package com.lianjia.sh.se.esb.server.log;

import com.alibaba.fastjson.JSONObject;
import com.lianjia.sh.se.esb.client.sender.MessageSender;
import com.lianjia.sh.se.esb.server.common.MessageConstants;
import com.lianjia.sh.se.esb.server.common.MessageLogRepeatStatus;
import com.lianjia.sh.se.esb.server.log.dao.MessageLogRepeatDao;
import com.lianjia.sh.se.esb.server.log.model.MessageLogRepeat;
import com.lianjia.sh.se.esb.spi.model.Message;
import com.lianjia.sh.se.esb.spi.model.impl.SimpleMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yangsp1 on 16/7/18.
 */
@Service
public class MessageLogRepeatService {
    @Autowired
    MessageSender messageSender;

    @Autowired
    MessageLogRepeatDao messageLogRepeatDao;
    /**
     * 插入或更新发送失败的日志
     * @param message
     */
    @Async
    public void insertOrUpdateRepeatFail(Message message,String actionType,Integer errMaxRepeatCnt){
        Map<String,Object> extendData = message.getExtendData();
        if(extendData == null){
            message.setExtendData(new HashMap<>());
            extendData = message.getExtendData();
        }

        //操作类型
        extendData.put("actionType",actionType);

        //已经重复次数
        Integer errRepeatCnt = (Integer)extendData.get("errRepeatCnt");
        if(errRepeatCnt == null){
            extendData.put("errRepeatCnt",0);
        }

        //最高重复次数
        if(errMaxRepeatCnt == null){
            errMaxRepeatCnt = 0;
        }
        extendData.put("errMaxRepeatCnt",errMaxRepeatCnt);

        //发送状态（成功或失败）
        // 可以重发：1 失败状态
        // 不可以重发（最高重发次数为0时：status=2；重发次数已经达到最高:status=3；重发成功：4；则为不可重发，此字段防止重发次数变更后影响历史数据）
        //
        extendData.put("status",1);

        MessageLogRepeat messageLogRepeat = new MessageLogRepeat();
        messageLogRepeat.setMsgUUId(message.getMsgUUId());
        messageLogRepeat.setActionType(actionType);
        messageLogRepeat.setProjectType(message.getProjectType());
        messageLogRepeat.setServiceType(message.getServiceType());
        messageLogRepeat.setStatus(1);
        messageLogRepeat.setData(JSONObject.toJSONString(message.getData()));
        if(message.getExtendData() != null) {
            messageLogRepeat.setExtendData(JSONObject.toJSONString(message.getExtendData()));
        }
        messageLogRepeat.setErrRepeatCnt((Integer)extendData.get("errRepeatCnt"));
        messageLogRepeat.setErrMaxRepeatCnt((Integer)extendData.get("errMaxRepeatCnt"));
        messageLogRepeat.setStatus((Integer)extendData.get("status"));

        //如果id不为空，则更新
        Long id = (Long) extendData.get("id");
        if(id != null){
            MessageLogRepeat messageLogRepeatOld = messageLogRepeatDao.findById(id);
            if(messageLogRepeatOld != null){
                Integer status = null;
                if(errMaxRepeatCnt <= (errRepeatCnt + 1)){
                    status = MessageLogRepeatStatus.达重发上限.value();
                }else{
                    status = messageLogRepeatOld.getStatus();
                }
                messageLogRepeatDao.update(id,messageLogRepeatOld.getErrRepeatCnt() + 1,status);
                return;
            }
        }

        //插入
        if(errMaxRepeatCnt <= 0) {
            extendData.put("status", MessageLogRepeatStatus.不需重发);
        }else{
            extendData.put("status", MessageLogRepeatStatus.需要重发);
        }
        messageLogRepeatDao.insert(messageLogRepeat );
    }


    /**
     * 更新发送成功的日志
     * @param message
     */
    @Async
    public void updateRepeatSuccess(Message message){
        Map<String,Object> extendData = message.getExtendData();
        if(extendData == null){
            message.setExtendData(new HashMap<>());
            extendData = message.getExtendData();
        }
        //如果id不为空，则更新
        Long id = (Long)extendData.get("id");
        if(id == null){
            return;
        }
        MessageLogRepeat messageLogRepeatOld = messageLogRepeatDao.findById(id);
        if(messageLogRepeatOld == null){
            return;
        }

        messageLogRepeatDao.update(id,messageLogRepeatOld.getErrRepeatCnt() + 1,MessageLogRepeatStatus.重发成功.value());

    }

    /**
     * 由定时任务调度：重新发送消息
     */
    @Async
    public void repeatSendMessage(){
        List<MessageLogRepeat> messages = messageLogRepeatDao.findTop(MessageConstants.MESSAGE_LOG_REPEAT_PAGE_SIZE + 1);

        while (true){
            for (int i = 0; i < messages.size() && i < MessageConstants.MESSAGE_LOG_REPEAT_PAGE_SIZE -1 ; i++){
                MessageLogRepeat messageLogRepeat = messages.get(i);
                SimpleMessage simpleMessage = new SimpleMessage();
                simpleMessage.setMsgUUId(messageLogRepeat.getMsgUUId());
                simpleMessage.setProjectType(messageLogRepeat.getProjectType());
                simpleMessage.setServiceType(messageLogRepeat.getServiceType());
                simpleMessage.setData(JSONObject.parse(messageLogRepeat.getData()));
                if(StringUtils.isNotBlank(messageLogRepeat.getExtendData())) {
                    simpleMessage.setExtendData(JSONObject.parseObject(messageLogRepeat.getExtendData()));
                }
                simpleMessage.setOperatorIp(messageLogRepeat.getOperatorIp());
                simpleMessage.setOperateTime(messageLogRepeat.getOperateTime());
                simpleMessage.setOperatorEmpNo(messageLogRepeat.getOperatorEmpNo());
                messageSender.sendMQMsgAsync(simpleMessage);
            }

        }

    }
}
